package com.hup.sokoban.service.main;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.hup.sokoban.constant.MapConstant;
import com.hup.sokoban.model.common.StepRecord;
import com.hup.sokoban.model.main.MapInfo;
import com.hup.utils.commons.exception.AppCommonException;
import com.hup.utils.commons.exception.AppExceptionHandler;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * 处理步数记录的本地文件读写功能
 * @author hugan
 * @date 2020/5/18
 */
@Log4j2
public class StepRecordService {

    /**
     * STEP_RECORD列表序列化时,外层list格式化,list子元素不格式化
     */
    private static final SerializeConfig STEP_RECORD_SERIALIZE_CONFIG;

    static {
        STEP_RECORD_SERIALIZE_CONFIG = new SerializeConfig();
        STEP_RECORD_SERIALIZE_CONFIG.put(StepRecord.class,
                (serializer, object, fieldName, fieldType, features)
                        -> serializer.out.write(JSON.toJSONString(object, SerializerFeature.SortField)));
    }

    /**
     * @return nullable-无文件,或文件数据异常时,返回null
     */
    public static List<StepRecord> readFile(MapInfo mapInfo, String ext) {
        String name = mapInfo.mapItem.getName();
        File file = new File(MapConstant.MAP_DIR + name + ext);
        if (!file.exists()) {
            return null;
        }
        try {
            String rec = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
            return JSONArray.parseArray(rec, StepRecord.class);
        } catch (Exception e) {
            AppExceptionHandler.handle("文件读取异常", e);
            return null;
        }
    }

    public static void saveFile(MapInfo mapInfo, String ext) {
        String name = mapInfo.mapItem.getName();
        File toSave = new File(MapConstant.MAP_DIR + name + ext);

        try (FileOutputStream fos = new FileOutputStream(toSave)) {
            ArrayList<StepRecord> data = MapConstant.EXT_PROGRESS.equals(ext) ? mapInfo.lstProgressRecord : mapInfo.lstWinningRecord;
            String rec = JSON.toJSONString(data, STEP_RECORD_SERIALIZE_CONFIG, SerializerFeature.PrettyFormat);
            log.debug("rec=[{}]", rec);
            fos.write(rec.getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            AppExceptionHandler.handle("文件写入异常", e);
            throw new AppCommonException("文件写入异常");
        }
    }

    public static void deleteFile(MapInfo mapInfo, String ext) {
        String name = mapInfo.mapItem.getName();
        File file = new File(MapConstant.MAP_DIR + name + ext);
        if (file.exists()) {
            boolean delete = file.delete();
            if (!delete) {
                log.warn("删除失败?={}", file);
            }
        } else {
            log.warn("文件不存在?={}", file);
        }
    }

}
